//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// This is a sample for BCGControlBar Library Professional Edition
// Copyright (C) 1998-2016 BCGSoft Ltd.
// All rights reserved.
//
// This source code can be used, distributed or modified
// only under terms and conditions 
// of the accompanying license agreement.
//*******************************************************************************
//
// ChartTernaryView.cpp : implementation file
//

#include "stdafx.h"
#include "bcgpchartexample.h"
#include "ChartTernaryView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CChartTernaryView

IMPLEMENT_DYNCREATE(CChartTernaryView, CBCGPChartExampleView)

CChartTernaryView::CChartTernaryView()
	: CBCGPChartExampleView(CChartTernaryView::IDD),
	m_brText(CBCGPColor::Maroon),
	m_brFill(CBCGPColor::Gold, CBCGPColor::White, CBCGPBrush::BCGP_GRADIENT_DIAGONAL_LEFT, .8),
	m_brBorder(CBCGPColor::Goldenrod)
{
	//{{AFX_DATA_INIT(CChartTernaryView)
	m_nMarkerSize = 0;
	m_nMarkerShape = 0;
	m_bShowDataLabels = TRUE;
	m_nDataLabelAngle = 3;
	//}}AFX_DATA_INIT
}

CChartTernaryView::~CChartTernaryView()
{
}

void CChartTernaryView::DoDataExchange(CDataExchange* pDX)
{
	CBCGPChartExampleView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CChartTernaryView)
	DDX_Control(pDX, IDC_DATA_LABELS, m_wndShowDataLabels);
	DDX_Control(pDX, IDC_DATA_LABEL_ANGLE, m_wndDataLabelAngle);
	DDX_Control(pDX, IDC_CHART, m_wndChart);
	DDX_CBIndex(pDX, IDC_DATA_MARKER_SIZE, m_nMarkerSize);
	DDX_CBIndex(pDX, IDC_DATA_MARKER_SHAPE, m_nMarkerShape);
	DDX_Check(pDX, IDC_DATA_LABELS, m_bShowDataLabels);
	DDX_CBIndex(pDX, IDC_DATA_LABEL_ANGLE, m_nDataLabelAngle);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CChartTernaryView, CBCGPChartExampleView)
	//{{AFX_MSG_MAP(CChartTernaryView)
	ON_BN_CLICKED(IDC_DATA_LABELS, OnUpdateChart)
	ON_CBN_SELENDOK(IDC_DATA_MARKER_SHAPE, OnUpdateChart)
	ON_CBN_SELENDOK(IDC_DATA_MARKER_SIZE, OnUpdateChart)
	ON_BN_CLICKED(IDC_DATA_MARKERS, OnUpdateChart)
	ON_CBN_SELENDOK(IDC_DATA_LABEL_ANGLE, OnUpdateChart)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChartTernaryView diagnostics

#ifdef _DEBUG
void CChartTernaryView::AssertValid() const
{
	CBCGPChartExampleView::AssertValid();
}

void CChartTernaryView::Dump(CDumpContext& dc) const
{
	CBCGPChartExampleView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CChartTernaryView message handlers

void CChartTernaryView::OnInitialUpdate() 
{
	CBCGPChartExampleView::OnInitialUpdate();
	
	if (m_bIsReady)
	{
		return;
	}

	CBCGPChartVisualObject* pChart = m_wndChart.GetChart();
	ASSERT_VALID(pChart);

	pChart->SetChartType(BCGPChartTernary);

	if (m_Feature == CDemoFeature::BCGP_TernaryBasic)
	{
		InitBasicTernaryChart(pChart);
	}
	else
	{
		InitAdvancedTernaryChart(pChart);
	}

	m_bIsReady = TRUE;

	OnUpdateChart();
}

void CChartTernaryView::InitBasicTernaryChart(CBCGPChartVisualObject* pChart)
{
	//----------------
	// Set axis names:
	//----------------
	pChart->GetChartAxis(BCGP_CHART_A_TERNARY_AXIS)->m_strAxisName = _T("Name A");
	pChart->GetChartAxis(BCGP_CHART_B_TERNARY_AXIS)->m_strAxisName = _T("Name B");
	pChart->GetChartAxis(BCGP_CHART_C_TERNARY_AXIS)->m_strAxisName = _T("Name C");

	for (int i = 0; i < 10; i++)
	{
		pChart->AddChartDataYY1Y2(Rand(0, 100), Rand(0, 100), Rand(0, 100));

		CString strName;
		strName.Format(_T("%d"), i + 1);

		pChart->SetDataPointDataLabelText(strName, i);
		pChart->SetDataPointCategoryName(strName, i);
	}

	pChart->GetSeries(0)->SetDataLabelSeparator(_T(" - "));
}

void CChartTernaryView::InitAdvancedTernaryChart(CBCGPChartVisualObject* pChart)
{
	for (int i = 0; i < 3; i++)
	{
		int nElementsInSeries = (int) Rand(10, 20); 

		for (int j = 0; j < nElementsInSeries; j++)
		{
			double dblValMain = Rand(900., 1000.);
			double dblValSecond = Rand(0., 200.);
			double dblValThird = Rand(0., 200.);

			switch (i)
			{
			case 0:
				pChart->AddChartDataYY1Y2(dblValMain, dblValSecond, dblValThird, i);
				break;

			case 1:
				pChart->AddChartDataYY1Y2(dblValSecond, dblValMain, dblValThird, i);
				break;

			case 2:
				pChart->AddChartDataYY1Y2(dblValSecond, dblValThird, dblValMain, i);
				break;
			}
		}

		CBCGPChartSeries* pSeries = pChart->GetSeries(i);

		pSeries->EnableAutoColorDataPoints(FALSE);
		pSeries->ShowMarker(TRUE);

		switch (i)
		{
		case 0:
			pSeries->m_strSeriesName = _T("Series A");
			pSeries->SetMarkerShape(BCGPChartMarkerOptions::MS_CIRCLE);
			break;
		
		case 1:
			pSeries->m_strSeriesName = _T("Series B");
			pSeries->SetMarkerShape(BCGPChartMarkerOptions::MS_RECTANGLE);
			break;

		case 2:
			pSeries->m_strSeriesName = _T("Series C");
			pSeries->SetMarkerShape(BCGPChartMarkerOptions::MS_TRIANGLE);
			break;
		}
	}

	CBCGPChartTernarySeries* pZone1Series = DYNAMIC_DOWNCAST(CBCGPChartTernarySeries, pChart->CreateSeries(_T("Central Zone")));
	int nZone1Idx = pChart->FindSeriesIndex(pZone1Series);

	pChart->AddChartDataYY1Y2(70., 15., 15., nZone1Idx);
	pChart->AddChartDataYY1Y2(15., 70., 15., nZone1Idx);
	pChart->AddChartDataYY1Y2(15., 15., 70., nZone1Idx);

	pZone1Series->SetCurveType(BCGPChartFormatSeries::CCT_SPLINE_HERMITE);
	pZone1Series->CloseShape(TRUE, TRUE);
	pZone1Series->ShowMarker(FALSE);
	pZone1Series->m_bIncludeSeriesToLegend = FALSE;

	CBCGPChartTernarySeries* pZone2Series = DYNAMIC_DOWNCAST(CBCGPChartTernarySeries, pChart->CreateSeries(_T("A Zone")));
	int nZone2Idx = pChart->FindSeriesIndex(pZone2Series);
	pChart->AddChartDataYY1Y2(100., 0., 0., nZone2Idx);
	pChart->AddChartDataYY1Y2(80., 20., 0., nZone2Idx);
	pChart->AddChartDataYY1Y2(80., 0., 20., nZone2Idx);

	pZone2Series->SetCurveType(BCGPChartFormatSeries::CCT_LINE);
	pZone2Series->CloseShape(TRUE, TRUE);
	pZone2Series->ShowMarker(FALSE);
	pZone2Series->m_bIncludeSeriesToLegend = FALSE;

	CBCGPChartTernarySeries* pZone3Series = DYNAMIC_DOWNCAST(CBCGPChartTernarySeries, pChart->CreateSeries(_T("B Zone")));
	int nZone3Idx = pChart->FindSeriesIndex(pZone3Series);
	pChart->AddChartDataYY1Y2(0., 100., 0., nZone3Idx);
	pChart->AddChartDataYY1Y2(20., 80., 0., nZone3Idx);
	pChart->AddChartDataYY1Y2(0., 80., 20., nZone3Idx);

	pZone3Series->SetCurveType(BCGPChartFormatSeries::CCT_LINE);
	pZone3Series->CloseShape(TRUE, TRUE);
	pZone3Series->ShowMarker(FALSE);
	pZone3Series->m_bIncludeSeriesToLegend = FALSE;


	CBCGPChartTernarySeries* pZone4Series = DYNAMIC_DOWNCAST(CBCGPChartTernarySeries, pChart->CreateSeries(_T("C Zone")));
	int nZone4Idx = pChart->FindSeriesIndex(pZone4Series);
	pChart->AddChartDataYY1Y2(0., 0., 100., nZone4Idx);
	pChart->AddChartDataYY1Y2(20., 0., 80., nZone4Idx);
	pChart->AddChartDataYY1Y2(0., 20., 80., nZone4Idx);

	pZone4Series->SetCurveType(BCGPChartFormatSeries::CCT_LINE);
	pZone4Series->CloseShape(TRUE, TRUE);
	pZone4Series->ShowMarker(FALSE);
	pZone4Series->m_bIncludeSeriesToLegend = FALSE;

	// make transparent zones
	pChart->SetThemeOpacity(30);

	// Mark zones
	CBCGPChartTernarySeries* pMarkSeries = DYNAMIC_DOWNCAST(CBCGPChartTernarySeries, pChart->CreateSeries(_T("Marks")));
	int nCenterMarkSeriesIdx = pChart->FindSeriesIndex(pMarkSeries);
	
	pMarkSeries->ShowDataLabel(TRUE);
	pMarkSeries->SetDataLabelDrawBorder(FALSE);
	pMarkSeries->SetDataLabelAngle(0);
	pMarkSeries->ShowMarker(FALSE);
	pMarkSeries->m_bIncludeSeriesToLegend = FALSE;

	pChart->AddChartDataYY1Y2(1., 1., 1., nCenterMarkSeriesIdx);
	pMarkSeries->OnSetDataPointDataLabelText(0, _T("Central Zone\nNormal Conditions"));
	pMarkSeries->SetDataLabelDropLineToMarker(FALSE, 0);

	pChart->AddChartDataYY1Y2(90., 5., 5., nCenterMarkSeriesIdx);
	pMarkSeries->OnSetDataPointDataLabelText(1, _T("A-Zone\nExtreme Concentrations"));
	pMarkSeries->SetDataLabelAngle(70, 1);
	pMarkSeries->SetDataLabelDropLineToMarker(TRUE, 1);
	pMarkSeries->SetDataLabelDistanceFromMarker(60, 1);

	pChart->AddChartDataYY1Y2(5., 90., 5., nCenterMarkSeriesIdx);
	pMarkSeries->OnSetDataPointDataLabelText(2, _T("B-Zone\nExtreme Concentrations"));
	pMarkSeries->SetDataLabelAngle(-15, 2);
	pMarkSeries->SetDataLabelDropLineToMarker(TRUE, 2);
	pMarkSeries->SetDataLabelDistanceFromMarker(60, 2);

	pChart->AddChartDataYY1Y2(5., 5., 90., nCenterMarkSeriesIdx);
	pMarkSeries->OnSetDataPointDataLabelText(3, _T("C-Zone\nExtreme Concentrations"));
	pMarkSeries->SetDataLabelAngle(10, 3);
	pMarkSeries->SetDataLabelDropLineToMarker(TRUE, 3);
	pMarkSeries->SetDataLabelDistanceFromMarker(100, 3);

	// Find minimum concentrations and values
	double dblMinAPerc = ((CBCGPChartTernarySeries*)pChart->GetSeries(0))->GetMinPercentage(CBCGPChartData::CI_Y);
	double dblMinBPerc = ((CBCGPChartTernarySeries*)pChart->GetSeries(1))->GetMinPercentage(CBCGPChartData::CI_Y1);
	double dblMinCPerc = ((CBCGPChartTernarySeries*)pChart->GetSeries(2))->GetMinPercentage(CBCGPChartData::CI_Y2);

	double dblMinAVal = ((CBCGPChartTernarySeries*)pChart->GetSeries(0))->GetMinValue(CBCGPChartData::CI_Y);
	double dblMinBVal = ((CBCGPChartTernarySeries*)pChart->GetSeries(1))->GetMinValue(CBCGPChartData::CI_Y1);
	double dblMinCVal = ((CBCGPChartTernarySeries*)pChart->GetSeries(2))->GetMinValue(CBCGPChartData::CI_Y2);

	// Add annotation text

	// Text 1
	CString strFormat = _T("Minimum Concentrations:\nComponent A: %.2f%%\nComponent B: %.2f%%\nComponent C: %.2f%%");
	CString strAnn;
	strAnn.Format(strFormat, dblMinAPerc, dblMinBPerc, dblMinCPerc);

	CBCGPChartTextObject* pAnn = new CBCGPChartTextObject (pChart, strAnn, 30, 30, m_brText, m_brFill, m_brBorder);
	pAnn->SetCoordinateMode(CBCGPChartObject::CM_PIXELS);
	pAnn->m_format.m_textFormat.Create(BCGPChartFormatLabel::m_strDefaultFontFamily, 14);
	pAnn->m_format.SetContentPadding(CBCGPSize(5., 5.));
	pAnn->SetRoundedShape();
	pAnn->SetShadow();
	
	pChart->AddChartObject(pAnn);

	pAnn->SetForeground();

	strFormat = _T("Minimum Values:\nComponent A: %.2f mg\nComponent B: %.2f mg\nComponent C: %.2f mg");
	strAnn.Format(strFormat, dblMinAVal, dblMinBVal, dblMinCVal);

	// Text 2
	pAnn = new CBCGPChartTextObject (pChart, strAnn, 30, 120, m_brText, m_brFill, m_brBorder);
	pAnn->SetCoordinateMode(CBCGPChartObject::CM_PIXELS);
	pAnn->m_format.m_textFormat.Create(BCGPChartFormatLabel::m_strDefaultFontFamily, 14);
	pAnn->m_format.SetContentPadding(CBCGPSize(5., 5.));
	pAnn->SetRoundedShape();
	pAnn->SetShadow();

	pChart->AddChartObject(pAnn);

	pChart->SetTernaryAxasLabelMode(CBCGPChartTernaryAxis::LM_NORMAL);

	m_bShowDataLabels = FALSE;
	m_wndShowDataLabels.EnableWindow(FALSE);

	UpdateData(FALSE);
}

void CChartTernaryView::OnUpdateChart() 
{
	UpdateData();

	m_wndDataLabelAngle.EnableWindow(m_bShowDataLabels);

	CBCGPChartVisualObject* pChart = m_wndChart.GetChart();
	ASSERT_VALID(pChart);

	for (int i = 0; i < 3; i++)
	{
		CBCGPChartSeries* pSeries = pChart->GetSeries(i);

		if (pSeries == NULL)
		{
			continue;
		}

		ASSERT_VALID(pSeries);
		pSeries->ShowMarker(TRUE);
		pSeries->SetMarkerShape((BCGPChartMarkerOptions::MarkerShape)m_nMarkerShape);
		pSeries->SetMarkerSize(max(7, 5 * (m_nMarkerSize + 1)));
	}

	double dblDataLabelAngle = (m_nDataLabelAngle - 2) * 45;

	pChart->ShowDataLabels(m_bShowDataLabels, TRUE, TRUE, dblDataLabelAngle);

	pChart->Redraw();
}
